package com.chixing.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chixing.entity.BusinessOutlets;
import com.chixing.entity.Car;
import com.chixing.entity.Img;
import com.chixing.entity.vo.CarAddress;
import com.chixing.entity.Customer;
import com.chixing.entity.vo.CarVO;
import com.chixing.mapper.BusinessOutletsMapper;
import com.chixing.mapper.CarMapper;
import com.chixing.mapper.CustomerMapper;
import com.chixing.mapper.ImgMapper;
import com.chixing.service.ICarService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chixing.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author shy
 * @since 2022-10-20
 */
@Service
@Slf4j
public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements ICarService {
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private CarMapper carMapper;
    @Autowired
    private BusinessOutletsMapper businessOutletsMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    private DefaultRedisScript script;
    @Autowired
    private ImgMapper imgMapper;


    //根据折扣降序排序，前3个
    @Cacheable(cacheNames = "hotProduct",key="'hot_product'")
    @Override
    public List<Car> getHotDiscountProduct() {
        QueryWrapper<Car> wrapper=new QueryWrapper<>();
        wrapper.orderByAsc("car_id");
        wrapper.select("car_id","car_name","other1");
        //设置分页信息,查询第1页,每页显示3条
        Page<Car> page=new Page<>(1,3);
        Page<Car> pageInfo=carMapper.selectPage(page,wrapper);
        List<Car> carList=pageInfo.getRecords();
        System.out.println("从mysql中查询出来的热门折扣商品："+carList);
        return carList;
    }

//    @Override
//    public Car getByCarId(Integer carId) {
//        return carMapper.selectById(carId);
//    }

    @Override
    public Car getByCarId(Integer carId) {
        String key = "car_carId_"+carId;
        ValueOperations<String,Car>  operations = redisTemplate.opsForValue();
        //判断redis中是否有键为key的缓存
        boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey){ //redis中有就去redis查数据
            Object object = operations.get(key);
            Car car = JSON.parseObject(JSON.toJSONString(object),Car.class);
            return car;
        }else {  //redis没有就去数据库查数据，再redis添加数据
            Car car = carMapper.selectById(carId);
            operations.set(key,car,24, TimeUnit.HOURS);
            return car;
        }

    }

    @Override
    public Car decreaseProductNumFromRedis(Integer carId) {
        Car car = null;
        String key = "scdKill_car_carId_"+carId;
        String uuid = UUID.randomUUID().toString().replace("-","");
        //获得锁
        boolean isLock = redisTemplate.opsForValue().setIfAbsent(key,uuid,24,TimeUnit.HOURS);
        if (isLock){  //获得到了锁
            car = (Car) redisTemplate.opsForValue().get(key);
            if (car == null){
                return null;
            }

            if (car.getCarStatus() == 0){ //如果车辆库存为0
                return null;
            }else { //减少库存
                car.setCarStatus(car.getCarStatus()-1);
                redisTemplate.opsForValue().set("scdKillCar_"+carId,car,24,TimeUnit.HOURS);

                //执行lua脚本，删除锁，保证原子性
                Long execute = (Long) redisTemplate.execute(script, Arrays.asList(key),uuid);
                return car;
            }
        }else {// 加锁失败，每隔0.1s 再获得锁
            try {
                Thread.sleep(100);
                car =(Car) redisTemplate.opsForValue().get("skillProduct_"+carId);
                if(carId != null && car.getCarStatus() >0) {
                    decreaseProductNumFromRedis(carId);
                    return car;
                }else
                    return null;
            } catch (InterruptedException e) {
                e.printStackTrace();
                return null;
            }

        }

    }

    @Override
    public List<Car> getCarByCustId(Integer custId) {
        Customer customer = customerMapper.selectById(custId);
        return null;
    }

//    @Override
//    public List<Car> getCarByCustId(Integer custId) {
//        Customer customer = customerMapper.selectById(custId);
//
//        return null;
//    }

    /**
     * 根据门店名称查询所有车辆
     * @param outletsName
     * @return 车辆列表
     */
    @Override
    public List<Car> getCarByOutletsName(String outletsName) {
        QueryWrapper<BusinessOutlets> qw1 = new QueryWrapper<>();
        System.out.println(outletsName);
        qw1.eq("outlets_name",outletsName);

        BusinessOutlets businessOutlets = businessOutletsMapper.selectOne(qw1);
        System.out.println(businessOutlets);
        QueryWrapper<Car> qw2 = new QueryWrapper<>();
        qw2.eq("other2",businessOutlets.getOutletsId());
        return carMapper.selectList(qw2);
    }

    /**
     * 查询car表内所有车辆
     * @return 所有的车辆的车辆列表
     */
    @Override
    public Result getAllCar() {
        ValueOperations<String,Car> operations = redisTemplate.opsForValue();

        //添加所有车辆到redis
        List<Car> carList = carMapper.selectList(null);
        for (Car car:carList){
            String key = "car_carId_" + car.getCarId();
            operations.set(key,car);
        }

        if (carList != null)
            return Result.success("查询所有车辆列表成功",carList);
        else
            return Result.fail("查询所有车辆列表失败",null);
    }

    @Override
    public Result getCarView() {
        List<Car> cars = carMapper.selectList(null);
        List<CarVO> carVOS = new ArrayList<>();
        for (Car c : cars) {
            CarVO carVO = new CarVO();
            BeanUtils.copyProperties(c,carVO);
            Img img = imgMapper.selectById(c.getCarImgId());
            BeanUtils.copyProperties(img,carVO);
            carVOS.add(carVO);
        }

        if (cars != null){

            return Result.success("查询成功",carVOS);
        }

        else{
            return Result.fail("查询失败",null);
        }
    }

    /**
     * 1.根据店面名称查询id
     * 2.根据id去查询car表当中的所有数据
     * @param name
     * @return 封装的CarAddress对象
     */
    @Override
    public CarAddress getCarAddress(String name) {
        //1.
        QueryWrapper<BusinessOutlets> qw = new QueryWrapper<>();
        qw.eq("outlets_name",name);
        BusinessOutlets businessOutlets = businessOutletsMapper.selectOne(qw);
        System.out.println("查询出的门店对象: "+businessOutlets);
        Integer outletsId = businessOutlets.getOutletsId();
        //2.
        QueryWrapper<Car> qw1 = new QueryWrapper<>();
        qw1.eq("other2",outletsId);
        List<Car> cars = carMapper.selectList(qw1);
        System.out.println("查询出的车辆列表: ");
        for (Car car : cars) {
            System.out.println(car);
        }
        CarAddress carAddress = new CarAddress();
        carAddress.setBusinessOutlets(businessOutlets);
        carAddress.setCarList(cars);

        System.out.println("封装之后的CarAddress对象: ");
        System.out.println(carAddress);

        return carAddress;
    }

}
